#include <stdio.h>
#include <stdarg.h>
#include "string.h"

#include "FreeRTOS.h"
#include "queue.h"
#include "task.h"
#include "semphr.h"

#include "hw_memmap.h"
#include "hw_types.h"
#include "hw_sysctl.h"
#include "hw_ints.h"

#include "gpio.h"

#include "Display.h"

#include "rit128x96x4.h"


/* Constants used when writing strings to the display. */
#define mainCHARACTER_HEIGHT				( 9 )
#define mainMAX_ROWS_128					( mainCHARACTER_HEIGHT * 14 )
#define mainMAX_ROWS_96						( mainCHARACTER_HEIGHT * 10 )
#define mainMAX_ROWS_64						( mainCHARACTER_HEIGHT * 7 )
#define mainFULL_SCALE						( 15 )
#define ulSSI_FREQUENCY						( 3500000UL )

#define mainMAX_MSG_LEN 14

#define bmpBITMAP_WIDTH 128
#define bmpBITMAP_HEIGHT 96


/* Functions to access the OLED.  The one used depends on the dev kit
being used. */
void ( *vOLEDInit )( unsigned portLONG ) = RIT128x96x4Init;
void ( *vOLEDStringDraw )( const portCHAR *, unsigned portLONG, unsigned portLONG, unsigned portCHAR ) = RIT128x96x4StringDraw;
void ( *vOLEDImageDraw )( const unsigned portCHAR *, unsigned portLONG, unsigned portLONG, unsigned portLONG, unsigned portLONG ) = RIT128x96x4ImageDraw;
void ( *vOLEDClear )( void ) = RIT128x96x4Clear;

xQueueHandle HandleOledQueue;

void Tarefa_Oled( void )
{
xOLEDMessage xMessage;
unsigned portLONG ulY, ulMaxY;
static portCHAR cMessage[ mainMAX_MSG_LEN ];
extern volatile unsigned portLONG ulMaxJitter;
unsigned portBASE_TYPE uxUnusedStackOnEntry;
const unsigned portCHAR *pucImage;

/* Just for demo purposes. */
	uxUnusedStackOnEntry = uxTaskGetStackHighWaterMark( NULL );


    ulMaxY = mainMAX_ROWS_96;
	ulY = ulMaxY;
	
	/* Initialise the OLED and display a startup message. */
	vOLEDInit( ulSSI_FREQUENCY );	
	vOLEDStringDraw( "String de teste", 0, 0, mainFULL_SCALE );
	//vOLEDImageDraw( pucImage, 0, mainCHARACTER_HEIGHT + 1, bmpBITMAP_WIDTH, bmpBITMAP_HEIGHT );
    vOLEDClear();
	
	for( ;; )
	{
		/* Wait for a message to arrive that requires displaying. */
		xQueueReceive( HandleOledQueue, &xMessage, portMAX_DELAY );
	
                //vOLEDClear();
                
                if(xMessage.isImage)
                {
                  vOLEDImageDraw(xMessage.pcMessage, 0, 0, bmpBITMAP_WIDTH, bmpBITMAP_HEIGHT );
                  continue;
                }
                
		/* Write the message on the next available row. 
		ulY += mainCHARACTER_HEIGHT;
		if( ulY >= ulMaxY )
		{
			ulY = mainCHARACTER_HEIGHT;
			vOLEDClear();
			vOLEDStringDraw( pcWelcomeMessage, 0, 0, mainFULL_SCALE );			
		}
         */
		sprintf( cMessage, "%s", xMessage.pcMessage);
	//	vOLEDStringDraw( cMessage, 0, ulY, mainFULL_SCALE );
                vOLEDStringDraw( cMessage, 0, xMessage.linha*mainCHARACTER_HEIGHT, mainFULL_SCALE );
                vPortFree(xMessage.pcMessage);
	}
}

void Funcao_OledPrintf2(char* frase, int linha)
{
  xOLEDMessage mensagem;
  mensagem.linha = linha;
  mensagem.isImage = false;
  mensagem.pcMessage = pvPortMalloc(strlen(frase)*sizeof(char));
  strcpy(mensagem.pcMessage, frase);
  xQueueSend(HandleOledQueue, &mensagem, portMAX_DELAY );  
}
void Funcao_OledClear( void )
{
    vOLEDClear();
}